package org.jsets.fastboot.util;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class ThreadLocals {
	
	private static final ThreadLocal<Map<String, Object>> LOCAL_MAP = new ThreadLocal<>();
	
	public static Object get(final String key) {
        final Map<String, Object> map = LOCAL_MAP.get();
        return map == null ? null : map.get(key);
    }
	
	public static void put(final String key, final Object value) {
		Map<String, Object> newMap = null;
		final Map<String, Object> map = LOCAL_MAP.get();
        if(null==map) {
        	newMap = new HashMap<>(1);
        }else {
        	newMap = new HashMap<>(map);
        	LOCAL_MAP.remove();
        }
        newMap.put(key, value);
        LOCAL_MAP.set(Collections.unmodifiableMap(newMap));
    }
    
	public static void remove(final String key) {
        final Map<String, Object> map = LOCAL_MAP.get();
        if (map != null) {
            final Map<String, Object> copy = new HashMap<>(map);
        	LOCAL_MAP.remove();
            copy.remove(key);
            LOCAL_MAP.set(Collections.unmodifiableMap(copy));
        }
    }
	
	public static void removeAll(final Iterable<String> keys) {
        final Map<String, Object> map = LOCAL_MAP.get();
        if (map != null) {
            final Map<String, Object> copy = new HashMap<>(map);
            LOCAL_MAP.remove();
            for (final String key : keys) {
                copy.remove(key);
            }
            LOCAL_MAP.set(Collections.unmodifiableMap(copy));
        }
    }
	
	public static Map<String, Object> getCopy() {
        final Map<String, Object> map = LOCAL_MAP.get();
        return map == null ? new HashMap<>() : new HashMap<>(map);
    }
    
	public static Map<String, Object> getImmutableMapOrNull() {
        return LOCAL_MAP.get();
    }
    
    @SuppressWarnings("unchecked")
    public static <V> V getValue(final String key) {
        final Map<String, Object> map = LOCAL_MAP.get();
        return (V) (map == null ? null : map.get(key));
    }
    
    public static boolean containsKey(final String key) {
        final Map<String, Object> map = LOCAL_MAP.get();
        return map != null && map.containsKey(key);
    }
    
    public static boolean isEmpty() {
        final Map<String, Object> map = LOCAL_MAP.get();
        return map == null || map.isEmpty();
    }
    
    public static void cleanup() {
    	LOCAL_MAP.remove();
    }
    
}